{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [],
   "source": [
    "%reload_ext autoreload\n",
    "%autoreload 2\n",
    "\n",
    "import numpy as np\n",
    "import pandas as pd\n",
    "import matplotlib\n",
    "\n",
    "from dsutil.plotting import add_grid,add_value_labels\n",
    "\n",
    "pd.set_option('display.max_columns',1000)\n",
    "\n",
    "import os\n",
    "\n",
    "import matplotlib.pyplot as plt\n",
    "%matplotlib inline\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "pandas: 1.0.5, numpy: 1.19.0, matplotlib: 3.2.2\n"
     ]
    }
   ],
   "source": [
    "print('pandas: {}, numpy: {}, matplotlib: {}'.format(\n",
    "    pd.__version__,\n",
    "    np.__version__,\n",
    "    matplotlib.__version__))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>user_id</th>\n",
       "      <th>content_id</th>\n",
       "      <th>tag</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>1</td>\n",
       "      <td>1</td>\n",
       "      <td>cool</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>2</td>\n",
       "      <td>1</td>\n",
       "      <td>nice</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>1</td>\n",
       "      <td>2</td>\n",
       "      <td>clever</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>3</td>\n",
       "      <td>2</td>\n",
       "      <td>clever</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>3</td>\n",
       "      <td>2</td>\n",
       "      <td>not-bad</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "   user_id  content_id      tag\n",
       "0        1           1     cool\n",
       "1        2           1     nice\n",
       "2        1           2   clever\n",
       "3        3           2   clever\n",
       "4        3           2  not-bad"
      ]
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "df = pd.DataFrame({\n",
    "    'user_id':[1,2,1,3,3,],\n",
    "    'content_id':[1,1,2,2,2],\n",
    "    'tag':['cool','nice','clever','clever','not-bad']\n",
    "})\n",
    "df"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>content_id</th>\n",
       "      <th>tag</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>1</td>\n",
       "      <td>cool,nice</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>2</td>\n",
       "      <td>clever,clever,not-bad</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "   content_id                    tag\n",
       "0           1              cool,nice\n",
       "1           2  clever,clever,not-bad"
      ]
     },
     "execution_count": 8,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "df.groupby(\"content_id\")['tag'].apply(lambda tags: ','.join(tags)).to_frame().reset_index()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>content_id</th>\n",
       "      <th>unique_users</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>1</td>\n",
       "      <td>2</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>2</td>\n",
       "      <td>2</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "   content_id  unique_users\n",
       "0           1             2\n",
       "1           2             2"
      ]
     },
     "execution_count": 9,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "df.groupby(\"content_id\")[\"user_id\"].nunique().to_frame().reset_index().rename(columns={\"user_id\":'unique_users'})"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "collapsed": true
   },
   "source": [
    "### sort groupby groups"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>value</th>\n",
       "      <th>product</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>20.45</td>\n",
       "      <td>table</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>22.89</td>\n",
       "      <td>chair</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>32.12</td>\n",
       "      <td>chair</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>111.22</td>\n",
       "      <td>mobile phone</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>33.22</td>\n",
       "      <td>table</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>5</th>\n",
       "      <td>100.00</td>\n",
       "      <td>mobile phone</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>6</th>\n",
       "      <td>99.99</td>\n",
       "      <td>table</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "    value       product\n",
       "0   20.45         table\n",
       "1   22.89         chair\n",
       "2   32.12         chair\n",
       "3  111.22  mobile phone\n",
       "4   33.22         table\n",
       "5  100.00  mobile phone\n",
       "6   99.99         table"
      ]
     },
     "execution_count": 10,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "df = pd.DataFrame({\n",
    "    'value':[20.45,22.89,32.12,111.22,33.22,100.00,99.99],\n",
    "    'product':['table','chair','chair','mobile phone','table','mobile phone','table']\n",
    "})\n",
    "df"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>product</th>\n",
       "      <th>value</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>chair</td>\n",
       "      <td>55.01</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>mobile phone</td>\n",
       "      <td>211.22</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>table</td>\n",
       "      <td>153.66</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "        product   value\n",
       "0         chair   55.01\n",
       "1  mobile phone  211.22\n",
       "2         table  153.66"
      ]
     },
     "execution_count": 11,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "df.groupby('product')['value'].sum().to_frame().reset_index()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>product</th>\n",
       "      <th>value</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>chair</td>\n",
       "      <td>55.01</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>table</td>\n",
       "      <td>153.66</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>mobile phone</td>\n",
       "      <td>211.22</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "        product   value\n",
       "0         chair   55.01\n",
       "2         table  153.66\n",
       "1  mobile phone  211.22"
      ]
     },
     "execution_count": 12,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "df.groupby('product')['value'].sum().to_frame().reset_index().sort_values(by='value')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "pandas.core.groupby.generic.SeriesGroupBy"
      ]
     },
     "execution_count": 13,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "type(df.groupby('product')['value'])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## plot group size"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.clf()\n",
    "df.groupby('product').size().plot(kind='bar')\n",
    "plt.xticks(rotation=0)\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## plot sum by group"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {
    "scrolled": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<Figure size 432x288 with 0 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.clf()\n",
    "df.groupby('product').sum().plot(kind='bar')\n",
    "plt.xticks(rotation=0)\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## plot group average with error bars"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>product</th>\n",
       "      <th>purchase_price</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>table</td>\n",
       "      <td>28.45</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>table</td>\n",
       "      <td>25.89</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>table</td>\n",
       "      <td>32.12</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>mobile phone</td>\n",
       "      <td>99.99</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>mobile phone</td>\n",
       "      <td>120.00</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>5</th>\n",
       "      <td>mobile phone</td>\n",
       "      <td>170.00</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>6</th>\n",
       "      <td>chair</td>\n",
       "      <td>12.22</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>7</th>\n",
       "      <td>chair</td>\n",
       "      <td>28.22</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>8</th>\n",
       "      <td>chair</td>\n",
       "      <td>5.00</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "        product  purchase_price\n",
       "0         table           28.45\n",
       "1         table           25.89\n",
       "2         table           32.12\n",
       "3  mobile phone           99.99\n",
       "4  mobile phone          120.00\n",
       "5  mobile phone          170.00\n",
       "6         chair           12.22\n",
       "7         chair           28.22\n",
       "8         chair            5.00"
      ]
     },
     "execution_count": 16,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "df = pd.DataFrame({\n",
    "    'product':['table','table','table','mobile phone','mobile phone','mobile phone','chair','chair','chair'],\n",
    "    'purchase_price':[28.45, 25.89,32.12,99.99,120.00,170.00,12.22,28.22,5.00]\n",
    "})\n",
    "df[['product','purchase_price']]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead tr th {\n",
       "        text-align: left;\n",
       "    }\n",
       "\n",
       "    .dataframe thead tr:last-of-type th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr>\n",
       "      <th></th>\n",
       "      <th colspan=\"2\" halign=\"left\">purchase_price</th>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th></th>\n",
       "      <th>mean</th>\n",
       "      <th>std</th>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>product</th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>chair</th>\n",
       "      <td>15.146667</td>\n",
       "      <td>11.883439</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>mobile phone</th>\n",
       "      <td>129.996667</td>\n",
       "      <td>36.059673</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>table</th>\n",
       "      <td>28.820000</td>\n",
       "      <td>3.131437</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "             purchase_price           \n",
       "                       mean        std\n",
       "product                               \n",
       "chair             15.146667  11.883439\n",
       "mobile phone     129.996667  36.059673\n",
       "table             28.820000   3.131437"
      ]
     },
     "execution_count": 17,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "df.groupby('product').agg([np.mean,np.std])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>product</th>\n",
       "      <th>mean</th>\n",
       "      <th>std</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>chair</td>\n",
       "      <td>15.15</td>\n",
       "      <td>11.88</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>mobile phone</td>\n",
       "      <td>130.00</td>\n",
       "      <td>36.06</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>table</td>\n",
       "      <td>28.82</td>\n",
       "      <td>3.13</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "        product    mean    std\n",
       "0         chair   15.15  11.88\n",
       "1  mobile phone  130.00  36.06\n",
       "2         table   28.82   3.13"
      ]
     },
     "execution_count": 18,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "v=df.groupby('product').agg([np.mean,np.std])\n",
    "\n",
    "v.columns = [col[-1].strip() for col in v.columns.values]\n",
    "\n",
    "\n",
    "for index,row in v.iterrows():\n",
    "    name = row.name\n",
    "    mean = row['mean']\n",
    "    stddev = row['std']    \n",
    "    \n",
    "v['mean'] = v['mean'].apply(lambda v: '{:.2f}'.format(v)) \n",
    "v['std'] = v['std'].apply(lambda v: '{:.2f}'.format(v)) \n",
    "\n",
    "v.reset_index()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.clf()\n",
    "\n",
    "ax = plt.gca()\n",
    "\n",
    "# plot the means\n",
    "df.groupby('product').mean().plot(kind='bar',color='lightblue',ax=ax)\n",
    "\n",
    "# generate a dataframe with means and standard deviations\n",
    "grouped_df=df.groupby('product').agg([np.mean,np.std])\n",
    "\n",
    "# flatten column names\n",
    "grouped_df.columns = [col.strip() for col in v.columns.values]\n",
    "\n",
    "# iterrows is usually very slow but since this is a grouped\n",
    "# dataframe, there wonly be many rows\n",
    "for i,(index,row) in enumerate(grouped_df.iterrows()):\n",
    "    name = row.name\n",
    "    mean = row['mean']\n",
    "    stddev = row['std']\n",
    "    \n",
    "    # plot the vertical line\n",
    "    ax.vlines(x=i,ymin=mean-stddev,ymax=mean+stddev)   \n",
    "        \n",
    "plt.xticks(rotation=0)\n",
    "add_grid()\n",
    "plt.ylabel('Average purchase price')\n",
    "plt.xlabel(None)\n",
    "plt.gca().legend_.remove()\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### flattening"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 43,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>value</th>\n",
       "      <th>product</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>20.45</td>\n",
       "      <td>table</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>22.89</td>\n",
       "      <td>chair</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>32.12</td>\n",
       "      <td>chair</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>111.22</td>\n",
       "      <td>mobile phone</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>33.22</td>\n",
       "      <td>table</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>5</th>\n",
       "      <td>100.00</td>\n",
       "      <td>mobile phone</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>6</th>\n",
       "      <td>99.99</td>\n",
       "      <td>table</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "    value       product\n",
       "0   20.45         table\n",
       "1   22.89         chair\n",
       "2   32.12         chair\n",
       "3  111.22  mobile phone\n",
       "4   33.22         table\n",
       "5  100.00  mobile phone\n",
       "6   99.99         table"
      ]
     },
     "execution_count": 43,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "df = pd.DataFrame({\n",
    "    'value':[20.45,22.89,32.12,111.22,33.22,100.00,99.99],\n",
    "    'product':['table','chair','chair','mobile phone','table','mobile phone','table']\n",
    "})\n",
    "df"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 44,
   "metadata": {},
   "outputs": [],
   "source": [
    "grouped_df = df.groupby('product').agg({'value':['min','max','mean']})"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 45,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead tr th {\n",
       "        text-align: left;\n",
       "    }\n",
       "\n",
       "    .dataframe thead tr:last-of-type th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr>\n",
       "      <th></th>\n",
       "      <th colspan=\"3\" halign=\"left\">value</th>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th></th>\n",
       "      <th>min</th>\n",
       "      <th>max</th>\n",
       "      <th>mean</th>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>product</th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>chair</th>\n",
       "      <td>22.89</td>\n",
       "      <td>32.12</td>\n",
       "      <td>27.505</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>mobile phone</th>\n",
       "      <td>100.00</td>\n",
       "      <td>111.22</td>\n",
       "      <td>105.610</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>table</th>\n",
       "      <td>20.45</td>\n",
       "      <td>99.99</td>\n",
       "      <td>51.220</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "               value                 \n",
       "                 min     max     mean\n",
       "product                              \n",
       "chair          22.89   32.12   27.505\n",
       "mobile phone  100.00  111.22  105.610\n",
       "table          20.45   99.99   51.220"
      ]
     },
     "execution_count": 45,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "grouped_df"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 46,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>product</th>\n",
       "      <th>value_min</th>\n",
       "      <th>value_max</th>\n",
       "      <th>value_mean</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>chair</td>\n",
       "      <td>22.89</td>\n",
       "      <td>32.12</td>\n",
       "      <td>27.505</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>mobile phone</td>\n",
       "      <td>100.00</td>\n",
       "      <td>111.22</td>\n",
       "      <td>105.610</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>table</td>\n",
       "      <td>20.45</td>\n",
       "      <td>99.99</td>\n",
       "      <td>51.220</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "        product  value_min  value_max  value_mean\n",
       "0         chair      22.89      32.12      27.505\n",
       "1  mobile phone     100.00     111.22     105.610\n",
       "2         table      20.45      99.99      51.220"
      ]
     },
     "execution_count": 46,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "grouped_df.columns = ['_'.join(col) for col in grouped_df.columns.values]\n",
    "grouped_df.reset_index()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### iterate over groups"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>value</th>\n",
       "      <th>product</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>20.45</td>\n",
       "      <td>table</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>22.89</td>\n",
       "      <td>chair</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>32.12</td>\n",
       "      <td>chair</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>111.22</td>\n",
       "      <td>mobile phone</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>33.22</td>\n",
       "      <td>table</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>5</th>\n",
       "      <td>100.00</td>\n",
       "      <td>mobile phone</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>6</th>\n",
       "      <td>99.99</td>\n",
       "      <td>table</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "    value       product\n",
       "0   20.45         table\n",
       "1   22.89         chair\n",
       "2   32.12         chair\n",
       "3  111.22  mobile phone\n",
       "4   33.22         table\n",
       "5  100.00  mobile phone\n",
       "6   99.99         table"
      ]
     },
     "execution_count": 24,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "df"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "the group for product 'chair' has 2 rows\n",
      "the group for product 'mobile phone' has 2 rows\n",
      "the group for product 'table' has 3 rows\n"
     ]
    }
   ],
   "source": [
    "for key,group_df in df.groupby('product'):\n",
    "    print(\"the group for product '{}' has {} rows\".format(key,len(group_df)))  "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## group by and change aggregation column name"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>value</th>\n",
       "      <th>product</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>20.45</td>\n",
       "      <td>table</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>22.89</td>\n",
       "      <td>chair</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>32.12</td>\n",
       "      <td>chair</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>111.22</td>\n",
       "      <td>mobile phone</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>33.22</td>\n",
       "      <td>table</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>5</th>\n",
       "      <td>100.00</td>\n",
       "      <td>mobile phone</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>6</th>\n",
       "      <td>99.99</td>\n",
       "      <td>table</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "    value       product\n",
       "0   20.45         table\n",
       "1   22.89         chair\n",
       "2   32.12         chair\n",
       "3  111.22  mobile phone\n",
       "4   33.22         table\n",
       "5  100.00  mobile phone\n",
       "6   99.99         table"
      ]
     },
     "execution_count": 26,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "df"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 27,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>product</th>\n",
       "      <th>value</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>chair</td>\n",
       "      <td>55.01</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>mobile phone</td>\n",
       "      <td>211.22</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>table</td>\n",
       "      <td>153.66</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "        product   value\n",
       "0         chair   55.01\n",
       "1  mobile phone  211.22\n",
       "2         table  153.66"
      ]
     },
     "execution_count": 27,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "df.groupby('product')['value'].sum().to_frame().reset_index()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 28,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>product</th>\n",
       "      <th>value_sum</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>chair</td>\n",
       "      <td>55.01</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>mobile phone</td>\n",
       "      <td>211.22</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>table</td>\n",
       "      <td>153.66</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "        product  value_sum\n",
       "0         chair      55.01\n",
       "1  mobile phone     211.22\n",
       "2         table     153.66"
      ]
     },
     "execution_count": 28,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "df.groupby('product')['value'].sum().reset_index(name='value_sum')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## get group by key"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 29,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>value</th>\n",
       "      <th>product</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>20.45</td>\n",
       "      <td>table</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>22.89</td>\n",
       "      <td>chair</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>32.12</td>\n",
       "      <td>chair</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>111.22</td>\n",
       "      <td>mobile phone</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>33.22</td>\n",
       "      <td>table</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>5</th>\n",
       "      <td>100.00</td>\n",
       "      <td>mobile phone</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>6</th>\n",
       "      <td>99.99</td>\n",
       "      <td>table</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "    value       product\n",
       "0   20.45         table\n",
       "1   22.89         chair\n",
       "2   32.12         chair\n",
       "3  111.22  mobile phone\n",
       "4   33.22         table\n",
       "5  100.00  mobile phone\n",
       "6   99.99         table"
      ]
     },
     "execution_count": 29,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "df"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 30,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>value</th>\n",
       "      <th>product</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>22.89</td>\n",
       "      <td>chair</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>32.12</td>\n",
       "      <td>chair</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "   value product\n",
       "1  22.89   chair\n",
       "2  32.12   chair"
      ]
     },
     "execution_count": 30,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# grouped_df is a DataFrameGroupBy containing each individual group as a dataframe\n",
    "grouped_df = df.groupby('product')\n",
    "\n",
    "# you get can a dataframe containing the values for a single group\n",
    "# using .get_group('group_key')\n",
    "grouped_df.get_group('chair')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## group into list"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 31,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>product</th>\n",
       "      <th>values</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>chair</td>\n",
       "      <td>[22.89, 32.12]</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>mobile phone</td>\n",
       "      <td>[100.0, 111.22]</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>table</td>\n",
       "      <td>[20.45, 33.22, 99.99]</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "        product                 values\n",
       "0         chair         [22.89, 32.12]\n",
       "1  mobile phone        [100.0, 111.22]\n",
       "2         table  [20.45, 33.22, 99.99]"
      ]
     },
     "execution_count": 31,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "df.groupby('product')['value'].apply(lambda group_series: sorted(group_series.tolist())).reset_index(name='values')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## custom aggregation function"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 32,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>value</th>\n",
       "      <th>product</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>20</td>\n",
       "      <td>table</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>22</td>\n",
       "      <td>chair</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>32</td>\n",
       "      <td>chair</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>111</td>\n",
       "      <td>mobile phone</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>33</td>\n",
       "      <td>table</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>5</th>\n",
       "      <td>100</td>\n",
       "      <td>mobile phone</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>6</th>\n",
       "      <td>99</td>\n",
       "      <td>table</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "   value       product\n",
       "0     20         table\n",
       "1     22         chair\n",
       "2     32         chair\n",
       "3    111  mobile phone\n",
       "4     33         table\n",
       "5    100  mobile phone\n",
       "6     99         table"
      ]
     },
     "execution_count": 32,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "df = pd.DataFrame({\n",
    "    'value':[20,22,32,111,33,100,99],\n",
    "    'product':['table','chair','chair','mobile phone','table','mobile phone','table']\n",
    "})\n",
    "\n",
    "df"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 33,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>product</th>\n",
       "      <th>num_even_numbers</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>chair</td>\n",
       "      <td>2</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>mobile phone</td>\n",
       "      <td>1</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>table</td>\n",
       "      <td>1</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "        product  num_even_numbers\n",
       "0         chair                 2\n",
       "1  mobile phone                 1\n",
       "2         table                 1"
      ]
     },
     "execution_count": 33,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "def count_even_numbers(series):\n",
    "    return len([elem for elem in series if elem % 2 == 0 ])\n",
    "\n",
    "df.groupby('product')['value'].apply(count_even_numbers).reset_index(name='num_even_numbers')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## stratified sampling"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 34,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>price</th>\n",
       "      <th>product</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>22</td>\n",
       "      <td>chair</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>32</td>\n",
       "      <td>chair</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>5</th>\n",
       "      <td>100</td>\n",
       "      <td>chair</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>20</td>\n",
       "      <td>table</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>111</td>\n",
       "      <td>table</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>33</td>\n",
       "      <td>table</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>6</th>\n",
       "      <td>99</td>\n",
       "      <td>table</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "   price product\n",
       "1     22   chair\n",
       "2     32   chair\n",
       "5    100   chair\n",
       "0     20   table\n",
       "3    111   table\n",
       "4     33   table\n",
       "6     99   table"
      ]
     },
     "execution_count": 34,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "df = pd.DataFrame({\n",
    "    'price':[20,22,32,111,33,100,99],\n",
    "    'product':['table','chair','chair','table','table','chair','table']\n",
    "})\n",
    "\n",
    "df.sort_values(by='product')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 35,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>price</th>\n",
       "      <th>product</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>22</td>\n",
       "      <td>chair</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>100</td>\n",
       "      <td>chair</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>111</td>\n",
       "      <td>table</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>99</td>\n",
       "      <td>table</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "   price product\n",
       "0     22   chair\n",
       "1    100   chair\n",
       "2    111   table\n",
       "3     99   table"
      ]
     },
     "execution_count": 35,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "df.groupby(\"product\").apply(\n",
    "    lambda group_df: group_df.sample(2)\n",
    ").reset_index(drop=True)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.9"
  },
  "toc": {
   "base_numbering": 1,
   "nav_menu": {},
   "number_sections": true,
   "sideBar": true,
   "skip_h1_title": false,
   "title_cell": "Table of Contents",
   "title_sidebar": "Contents",
   "toc_cell": false,
   "toc_position": {},
   "toc_section_display": true,
   "toc_window_display": false
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
